# This file is used to create a login blueprint for the flask application.
# The blueprint is used to handle the login functionality of the application.


from flask import Blueprint
from flask import request
from flask import jsonify
import psycopg2.extras
from database import db_pool_singleton
from database.user_info_table_method import UserInfoTableMethod
from database.user_token_table_method import UserTokenTableMethod
from database.user_login_log_table_method import UserLoginLogTableMethod
from database.user_operation_log_table_method import UserOperationLogTableMethod

login_blueprint = Blueprint('login', __name__)

@login_blueprint.route('/login', methods=['POST'])
def login():
    username = request.form.get('username')
    password = request.form.get('password')

    if not username or not password:
        args_error = {
            "status": -1,
            "errorCode": 1001,
            "errorMsg": "Username and password are required",
            "resultBody": {}
        }
        return jsonify(args_error)
    
    # Check if the user exists in the database
    with db_pool_singleton.getconn() as conn:
        cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) # cursor for executing queries
        user_info_table_method = UserInfoTableMethod(conn, cur)
        user_login_log_table_method = UserLoginLogTableMethod(conn, cur)
        user_info = user_info_table_method.select_user_info_by_username_and_password(username, password)
        # If the user and password are correct, get the user information from the database
        if not user_info:
            password_error = {
                "status": -1,
                "errorCode": 1002,
                "errorMsg": "Username or password is incorrect",
                "resultBody": {}
            }

            return jsonify(password_error)
        
        else:
            # Generate a token for the user and insert it into the user_token table
            token = UserTokenTableMethod(conn, cur).insert_user_token(user_info["user_id"])
            login_success = {
                "status": 1,
                "errorCode": None,
                "errorMsg": None,
                "resultBody": {
                    "user_id": user_info["user_id"],
                    "username": user_info["username"],
                    "phone": user_info["phone"],
                    "account_status": user_info["account_status"],
                    "token" : token                
                }
            }


            # Insert the login log into the user_login_log table
            user_login_log_table_method.insert_user_login_log(user_info["user_id"], request.remote_addr, request.user_agent.string)

            return jsonify(login_success)
        

@login_blueprint.route('/logout', methods=['POST'])
def logout():    
    user_id = request.form.get('user_id')

    if not user_id:

        args_error = {
            "status": -1,
            "errorCode": 1003,
            "errorMsg": "user_id is required",
            "resultBody": {}
        }
        return jsonify(args_error)
    
    # Delete the token from the user_token table
    with db_pool_singleton.getconn() as conn:
        cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) # cursor for executing queries
        user_token_table_method = UserTokenTableMethod(conn, cur)
        user_token_table_method.delete_user_token_by_user_id(user_id)
        logout_success = {
            "status": 1,
            "errorCode": None,
            "errorMsg": None,
            "resultBody": "Logout success"
        }

        # Insert the logout log into the user_operation_log table
        UserOperationLogTableMethod(conn, cur).insert_user_operation_log(user_id, "logout", "logout success")
        return jsonify(logout_success)
        
# 主要用来测试
@login_blueprint.route('/token_validate')
def token_validate():
    user_id = request.args.get('user_id')
    if not user_id:
        args_error = {
            "status": -1,
            "errorCode": 1004,
            "errorMsg": "user_id is required",
            "resultBody": {}
        }
        return jsonify(args_error)
    
    # Check if the user_id token is valid
    with db_pool_singleton.getconn() as conn:
        cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) # cursor for executing queries
        user_token_table_method = UserTokenTableMethod(conn, cur)
        token = user_token_table_method.get_user_token_by_user_id(user_id)
        if not token:
            token_error = {
                "status": -1,
                "errorCode": 1004,
                "errorMsg": "Token is invalid or expired",
                "resultBody": {}
            }
            return jsonify(token_error)
        else:
            token_valid = {
                "status": 1,
                "errorCode": None,
                "errorMsg": None,
                "resultBody": {
                    "user_id": user_id,
                    "token": token
                }
            }
            return jsonify(token_valid)
